home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / confvars.i < prev    next >
Text File  |  1997-10-26  |  30KB  |  991 lines

  1. IMPLEMENTATION MODULE ConfVars;
  2.  
  3. FROM SYSTEM      IMPORT ADDRESS, ADR, TSIZE;
  4. FROM GrafBase    IMPORT Rectangle;
  5. FROM Storage     IMPORT ALLOCATE, DEALLOCATE, MemSize;
  6.  
  7. (*
  8. FROM InOut IMPORT WriteString, WriteInt, WriteLn, Read;
  9. *)
  10. FROM Void        IMPORT v;
  11. IMPORT Lists;
  12. IMPORT Strings;
  13. IMPORT StrConv;
  14. IMPORT BinOps;
  15.  
  16. IMPORT MagicAES;
  17. IMPORT mtAlerts;
  18. IMPORT mtTextfiles;
  19. IMPORT Characters;
  20. IMPORT FileNames;
  21.  
  22. CONST   configVersion = '1.3 Dec 16 1996,';
  23.         copyRight     = ' ½ 1992-1997 Dirk Steins';
  24.         whatString    = '@(#)ConfigVars ' + configVersion+copyRight+0C;
  25.         equalSignCol  = 30;
  26.         configRequest = 'ConfigRequestFile';
  27.  
  28. TYPE MaxStr  = ARRAY [0..511] OF CHAR;
  29.      strPtr  = POINTER TO MaxStr;
  30.      
  31.      varType = (noVar, comment, int, lint, string, rect, bool);
  32.  
  33.      varVal  = RECORD CASE : varType OF
  34.                  int    : intV : INTEGER; |
  35.                  lint   : lintV: LONGINT; |
  36.                  string : strV : strPtr; |
  37.                  rect   : rectV : Rectangle; |
  38.                  bool   : boolV : BOOLEAN; |
  39.                  END;
  40.                END;
  41.  
  42.      confVar = RECORD
  43.                  type : varType;
  44.                  val  : varVal;
  45.                  name : MaxStr;
  46.                END;
  47.      varPtr  = POINTER TO confVar;
  48.  
  49. TYPE ErrorIndicator = (noBool, noInt, noRect, noString, syntaxErr, typeErr);
  50.  
  51. VAR confVars : Lists.List;
  52.     normalVars,
  53.     tmpVars  : Lists.List;
  54.  
  55.     deskSize : Rectangle;
  56.     
  57.     reqF     : BOOLEAN;
  58.     reqFile  : mtTextfiles.TEXTFILE;
  59.  
  60. (*$Z-*)
  61. PROCEDURE findName (entry : ADDRESS; info : ADDRESS) : BOOLEAN;
  62.   VAR theVar : varPtr;
  63.       theName: strPtr;
  64. BEGIN
  65.   theVar := varPtr (entry);
  66.   theName := strPtr (info);
  67.   RETURN Strings.StrEqual (theVar^.name, theName^);
  68. END findName;
  69. (*$Z=*)
  70.  
  71. (*$W-*)
  72. PROCEDURE findConfVar (REF name : ARRAY OF CHAR; VAR var : varPtr) : BOOLEAN;
  73.   VAR found : BOOLEAN;
  74. BEGIN
  75.   Lists.ResetList (confVars);
  76.   Lists.ScanEntries (confVars, Lists.forward, findName, ADR (name), found);
  77.   IF found THEN
  78.     var := varPtr (Lists.CurrentEntry (confVars));
  79.   ELSE
  80.     var := NIL;
  81.   END;
  82.   RETURN found  & (var # NIL);
  83. END findConfVar;
  84. (*$W+*)
  85.  
  86. (* Umrechnungsprozeduren *)
  87. CONST   ndcBase = 32767.0;
  88.  
  89. PROCEDURE RC2NDC (VAR r : Rectangle);
  90.   VAR tw, th : REAL;
  91.   
  92.   PROCEDURE LowerReal (x, y : REAL): REAL;
  93.   BEGIN
  94.     IF x > y THEN RETURN y ELSE RETURN x END;
  95.   END LowerReal;
  96.   
  97. BEGIN
  98.   tw := FLOAT(deskSize.x + deskSize.w);
  99.   th := FLOAT(deskSize.y + deskSize.h);
  100.   WITH r DO
  101.     x := VAL (INTEGER, LowerReal (ndcBase, (ndcBase / tw) * FLOAT(x)));
  102.     y := VAL (INTEGER, LowerReal (ndcBase, (ndcBase / th) * FLOAT(y)));
  103.     w := VAL (INTEGER, LowerReal (ndcBase, (ndcBase / tw) * FLOAT(w)));
  104.     h := VAL (INTEGER, LowerReal (ndcBase, (ndcBase / th) * FLOAT(h)));
  105.   END;
  106. END RC2NDC;
  107.  
  108. PROCEDURE NDC2RC (VAR r : Rectangle);
  109.   VAR tw, th : REAL;
  110. BEGIN
  111.   tw := FLOAT(deskSize.x + deskSize.w);
  112.   th := FLOAT(deskSize.y + deskSize.h);
  113.   WITH r DO
  114.     x := VAL (INTEGER, 0.5 + (FLOAT(x) * tw) / ndcBase);
  115.     y := VAL (INTEGER, 0.5 + (FLOAT(y) * th) / ndcBase);
  116.     w := VAL (INTEGER, 0.5 + (FLOAT(w) * tw) / ndcBase);
  117.     h := VAL (INTEGER, 0.5 + (FLOAT(h) * th) / ndcBase);
  118.   END;
  119. END NDC2RC;
  120.  
  121. PROCEDURE setVar (theVar : confVar) : BOOLEAN;
  122. (* ver„ndert eine vorhandene Variable oder erzeugt eine neue 
  123.  *)
  124.  VAR newVar : varPtr;
  125. BEGIN
  126.   IF ~findConfVar (theVar.name, newVar)
  127.   THEN
  128.     ALLOCATE (newVar, TSIZE (varType)+TSIZE (varVal) + LONG(LENGTH (theVar.name)+1));
  129.     IF newVar = NIL 
  130.     THEN RETURN FALSE
  131.     END;
  132.     newVar^.type := theVar.type;
  133.     newVar^.val  := theVar.val;
  134.     Strings.Assign (theVar.name, newVar^.name, v.bool);
  135.     Lists.AppendEntry (confVars, newVar, v.bool);
  136.     IF v.bool THEN RETURN FALSE END;
  137.   ELSE
  138.     IF (newVar^.type = lint)
  139.      & (theVar.type = int)
  140.     THEN
  141.       (* Kompatibilit„t von lInt und int *)
  142.       newVar^.type := theVar.type;
  143.       newVar^.val  := theVar.val;
  144.       RETURN TRUE;
  145.     ELSIF (newVar^.type = int)
  146.         & (theVar.type = lint)
  147.     THEN
  148.       (* Bereichsprfung und dann zuweisen *)
  149.       newVar^.type := theVar.type;
  150.       newVar^.val := theVar.val;
  151.     ELSIF newVar^.type # theVar.type THEN 
  152.       RETURN FALSE 
  153.     END;
  154.     IF theVar.type = string
  155.     THEN
  156.       DEALLOCATE (newVar^.val.strV, 0);
  157.       newVar^.val.strV := theVar.val.strV;
  158.     ELSE
  159.       newVar^.val := theVar.val;
  160.     END;
  161.   END;
  162.   RETURN TRUE;
  163. END setVar;
  164.  
  165. PROCEDURE prep (REF in: ARRAY OF CHAR; VAR name, arg : ARRAY OF CHAR);
  166.   VAR tmp : ARRAY [0..255] OF CHAR;
  167.       i   : INTEGER;
  168.       len : INTEGER;
  169.   BEGIN
  170.     (* Anpassung an Whitespace *)
  171.     i := 0;
  172.     len := LENGTH (in);
  173.     WHILE ( NOT Characters.IsSpace(in[i])) & (i < len) DO INC (i); END;
  174.     Strings.Split (in, i , name,arg, v.bool);
  175.     Strings.DelLeadingBlanks (arg);
  176.     Strings.Split (arg, Strings.PosLen ('=',arg,0)+1,tmp, arg, v.bool);
  177.     IF arg[0] = 0C THEN Strings.Assign (tmp, arg, v.bool) END;
  178.     Strings.DelLeadingBlanks (arg);
  179.     (* YYYY Hier noch Semikolon-Abfrage „ndern *)
  180.     Strings.Split (arg, Strings.PosLen (';',arg,0),arg, tmp, v.bool);
  181.     Strings.DelLeadingBlanks (arg);
  182.     Strings.DelTrailingBlanks (arg);
  183.   END prep;
  184.  
  185. PROCEDURE getNameAndType (REF line : ARRAY OF CHAR; 
  186.                           VAR name, argStr : ARRAY OF CHAR; 
  187.                           errorType : ErrorIndicator) : varType;
  188.   VAR theType : varType;
  189. BEGIN
  190.   prep (line, name, argStr);
  191.   IF (name[0] = ';') OR (name[0] = '#') OR (name[0] = 0C) THEN RETURN comment END;
  192.   IF (argStr[0] = 0C) THEN 
  193.     errorType := syntaxErr; RETURN noVar 
  194.   END;
  195.   theType := noVar;
  196.   CASE argStr[0] OF 
  197.     '0'..'9',
  198.     '-' : (* int gefunden *) 
  199.           theType := lint;|
  200.     '{' : (* Rectangle *) 
  201.           theType := rect; |
  202.     'O', 
  203.     'T', 
  204.     'F' : (* Boolean *) 
  205.           theType := bool; |
  206.     '"',
  207.     "'" : IF argStr[0] = argStr[LENGTH(argStr)-1] 
  208.           THEN
  209.             theType := string
  210.           END;
  211.   ELSE
  212.   END;
  213.   IF theType = noVar THEN errorType := typeErr END;
  214.   RETURN theType;
  215. END getNameAndType;
  216.  
  217. PROCEDURE processLine (REF fname, line : ARRAY OF CHAR; lineNumber : INTEGER) : BOOLEAN;
  218.   VAR theVar : confVar;
  219.       newVar : varPtr;  (* Dieser wird alloziert *)
  220.       error  : BOOLEAN;
  221.       errorType : ErrorIndicator;
  222.       alt       : MaxStr;
  223.       argStr,
  224.       valStr    : ARRAY [0..511] OF CHAR;
  225.  
  226. PROCEDURE getInfoBool (REF arg : ARRAY OF CHAR; VAR o : BOOLEAN);
  227.   BEGIN
  228.     IF Strings.StrEqual ('ON', arg) OR Strings.StrEqual ('TRUE', arg)
  229.     THEN o := TRUE
  230.     ELSIF Strings.StrEqual ('OFF', arg) OR Strings.StrEqual ('FALSE', arg)
  231.     THEN o := FALSE;
  232.     ELSE
  233.       error := TRUE;
  234.       errorType := noBool;
  235.     END;
  236.   END getInfoBool;
  237.   
  238. PROCEDURE getInfoInt (REF arg : ARRAY OF CHAR; VAR l: LONGINT);
  239.   VAR i: CARDINAL;
  240.       t: LONGINT;
  241.   BEGIN
  242.     i:= 0;
  243.     t:= StrConv.StrToLInt (arg, i, v.bool);
  244.     IF ~v.bool
  245.     THEN
  246.       error := TRUE;
  247.       errorType := noInt;
  248.     END;
  249.     l := t;
  250.   END getInfoInt;
  251.   
  252.   PROCEDURE getInfoRect (REF arg : ARRAY OF CHAR; VAR r : Rectangle);
  253.    VAR p, i : CARDINAL;
  254.           ra   : ARRAY [0..3] OF INTEGER;
  255.     BEGIN
  256.       p := 0; (* pos *)
  257.       FOR i := 0 TO 3 DO
  258.         WHILE (arg[p] = ' ') OR (arg[p] = '{') OR (arg[p]=',') DO INC (p) END;
  259.         ra[i] := StrConv.StrToInt (arg, p, v.bool);
  260.         IF ~v.bool
  261.         THEN
  262.           error := TRUE;
  263.           errorType := noRect;
  264.           RETURN
  265.         END;
  266.       END;
  267.       r.x := ra[0];
  268.       r.y := ra[1];
  269.       r.w := ra[2];
  270.       r.h := ra[3];
  271.       
  272.       NDC2RC(r);
  273.  
  274.       IF r.x + r.w < deskSize.x THEN r.x := deskSize.x END;
  275.       IF r.x > deskSize.x+deskSize.w THEN r.x := deskSize.x+deskSize.w-40 END;
  276.       IF r.y < deskSize.y THEN r.y := deskSize.y END;
  277.       IF r.y > deskSize.y+deskSize.h THEN r.y := deskSize.y+deskSize.h-40 END;
  278.       IF r.w < 0 THEN r.w := 80 END;
  279.       r.w := BinOps.LowerInt (r.w, deskSize.w);
  280.       IF r.h < 0 THEN r.h := 120 END;
  281.       r.h := BinOps.LowerInt (r.h, deskSize.h);
  282.     END getInfoRect;
  283.  
  284.   PROCEDURE getInfoStr (arg : ARRAY OF CHAR; VAR str : ARRAY OF CHAR);
  285.     VAR pos : INTEGER;
  286.         numStr : ARRAY [0..9] OF CHAR;
  287.         p1  : CARDINAL;
  288.   BEGIN
  289.       IF LENGTH (arg) > 0
  290.       THEN
  291.         arg[LENGTH(arg)-1] := 0C;            (* hinteres Anfhrungszeichen l”schen *)
  292.         Strings.Delete (arg, 0, 1, v.bool);  (* vorderes Anfhrungszeichen l”schen *)
  293.         Strings.Assign (arg,str, v.bool);
  294.         (* Sonderzeichen bersetzen *)
  295.         pos := 0;
  296.         WHILE pos >= 0 DO 
  297.           pos := Strings.Pos ('\', str, pos);
  298.           IF pos >= 0
  299.           THEN
  300.             (* Feststellen, ob die n„chsten drei Zahlen sind *)
  301.             Strings.Copy (str, pos+1, 3, numStr, v.bool);
  302.             IF Characters.IsDigit (numStr[0])
  303.              & Characters.IsDigit (numStr[1])
  304.              & Characters.IsDigit (numStr[2])
  305.             THEN
  306.               Strings.Delete (str, pos, 4, v.bool);
  307.               p1 := 0;
  308.               Strings.Insert (CHR(StrConv.StrToCard (numStr, p1, v.bool)), pos, str, v.bool);
  309.             ELSIF (numStr[0] = '\')
  310.             THEN
  311.               (* Ein \ entfernen *)
  312.               Strings.Delete (str, pos, 1, v.bool);
  313.               INC(pos);
  314.             ELSE
  315.               INC(pos);
  316.             END;
  317.           END;
  318.         END;
  319.       ELSE
  320.         error := TRUE;
  321.         errorType := noString;
  322.       END;
  323.     END getInfoStr;
  324.  
  325. BEGIN
  326.   error := FALSE;
  327.   CASE getNameAndType (line, theVar.name, argStr, errorType) OF
  328.     lint  : getInfoInt (argStr, theVar.val.lintV); 
  329.             IF (theVar.val.lintV <= 32767) & (theVar.val.lintV >= -32768)
  330.             THEN
  331.               theVar.val.intV := SHORT(theVar.val.lintV);
  332.               theVar.type := int; 
  333.             ELSE
  334.               theVar.type := lint;
  335.             END;|
  336.     bool  : getInfoBool (argStr, theVar.val.boolV);  theVar.type := bool; |
  337.     rect  : getInfoRect (argStr, theVar.val.rectV);  theVar.type := rect; |
  338.     string: getInfoStr  (argStr, valStr);
  339.             IF ~error THEN
  340.               ALLOCATE (theVar.val.strV, LENGTH (valStr)+1);
  341.               IF theVar.val.strV = NIL THEN RETURN FALSE END;
  342.               Strings.Assign (valStr, theVar.val.strV^, v.bool);
  343.               theVar.type := string; 
  344.             END; |
  345.     comment: RETURN TRUE |
  346.   ELSE
  347.     error := TRUE;
  348.   END;
  349.   IF error
  350.   THEN
  351.     (* Fehlermeldung ausgeben *)
  352.     Strings.Assign ('[3][CAT:|Fehler in INF-File|',alt, v.bool);
  353.     Strings.Append (fname, alt, v.bool);
  354.     Strings.Append (':|', alt, v.bool);
  355.     CASE errorType OF
  356.       noInt    : Strings.Append ('Keine Integerzahl',alt, v.bool); |
  357.       noBool   : Strings.Append ('Kein Boolean ',alt, v.bool); |
  358.       noString : Strings.Append ('Kein String',alt, v.bool); | 
  359.       noRect   : Strings.Append ('Kein Rechteck',alt, v.bool); | 
  360.       syntaxErr: Strings.Append ('Syntaxfehler', alt, v.bool); |
  361.       typeErr  : Strings.Append ('Typ nicht erkannt', alt, v.bool); |
  362.     ELSE
  363.     END;
  364.     Strings.Append ('|in Zeile: ',alt, v.bool);
  365.     Strings.Append (StrConv.IntToStr (lineNumber,0), alt, v.bool);
  366.     Strings.Append ('][ [OK ]', alt, v.bool);
  367.  
  368.     mtAlerts.SetIconColor (MagicAES.RED);
  369.     v.int := mtAlerts.Alert (1,alt);
  370.     RETURN TRUE;
  371.   END;
  372.   (* Variable richtig eingelesen, also weitermachen *)
  373.   RETURN setVar (theVar);
  374. END processLine;
  375.  
  376. PROCEDURE buildBool (value: BOOLEAN; VAR str: ARRAY OF CHAR);
  377. BEGIN
  378.   IF value THEN Strings.Assign ('TRUE', str, v.bool);
  379.   ELSE Strings.Assign ('FALSE', str, v.bool);
  380.   END;
  381. END buildBool;
  382.  
  383. PROCEDURE writeName (inf: mtTextfiles.TEXTFILE; REF name: ARRAY OF CHAR);
  384. BEGIN
  385.   mtTextfiles.WriteLine (inf,name);
  386.   mtTextfiles.WriteLine (inf, Strings.Space (BinOps.HigherInt (1, INTEGER(equalSignCol)-INTEGER(Strings.Length(name)))));
  387.   mtTextfiles.WriteLine (inf, ' := ');
  388. END writeName;
  389.  
  390. (*$W-*)
  391. PROCEDURE writeInfoBool (inf : mtTextfiles.TEXTFILE; REF name : ARRAY OF CHAR; value : BOOLEAN);
  392.   VAR str : MaxStr;
  393. BEGIN
  394.   writeName (inf,name);
  395.   buildBool (value, str);
  396.   mtTextfiles.WriteLine (inf, str);
  397.   mtTextfiles.WriteChar (inf, ';');
  398.   mtTextfiles.WriteLn(inf);
  399. END writeInfoBool;
  400.  
  401. PROCEDURE writeInfoInt (inf : mtTextfiles.TEXTFILE; REF name : ARRAY OF CHAR; value : LONGINT);
  402. BEGIN
  403.   writeName (inf, name);
  404.   mtTextfiles.WriteLongInt (inf, value, 0);
  405.   mtTextfiles.WriteChar (inf, ';');
  406.   mtTextfiles.WriteLn(inf);
  407. END writeInfoInt;
  408.  
  409. PROCEDURE buildStr (REF value: ARRAY OF CHAR; VAR str: ARRAY OF CHAR);
  410.   VAR val : ARRAY [0..511] OF CHAR;
  411.       num : ARRAY [0..9] OF CHAR;
  412.       i, j: INTEGER;
  413. BEGIN
  414.   IF LENGTH (value) > 0
  415.   THEN
  416.     (* Sonderzeichen in String bersetzen *)
  417.     j := 0;
  418.     FOR i := 0 TO INTEGER(LENGTH (value))-1 DO
  419.       IF (ORD(value[i]) >= 32) & (value[i] # ';')
  420.       THEN
  421.         val[j] := value[i];
  422.         IF (val[j] = '\')
  423.         THEN
  424.           (* '\' verdoppeln *)
  425.           INC (j);
  426.           val[j] := '\';
  427.         END;
  428.         INC (j);
  429.       ELSE
  430.         val[j] := '\';
  431.         Strings.Assign (StrConv.NumToStr(ORD(value[i]), 10, 3, '0'), num, v.bool);
  432.         val[j+1] := num[0];
  433.         val[j+2] := num[1];
  434.         val[j+3] := num[2];
  435.         INC (j, 4);
  436.       END;
  437.     END (* FOR *);
  438.     val[j] := 0C;
  439.     Strings.Assign (val, str, v.bool);
  440.   ELSE
  441.     Strings.Assign ("", str, v.bool);
  442.   END;
  443. END buildStr;
  444.  
  445. PROCEDURE writeInfoStr (inf : mtTextfiles.TEXTFILE; REF name : ARRAY OF CHAR; REF value : ARRAY OF CHAR);
  446.   VAR str: MaxStr;
  447. BEGIN
  448.   IF LENGTH (value) > 0 
  449.   THEN
  450.     writeName (inf, name);
  451.     mtTextfiles.WriteLine (inf, '"');
  452.     buildStr (value, str);
  453.     mtTextfiles.WriteLine (inf, str);
  454.     mtTextfiles.WriteLine (inf, '";');
  455.     mtTextfiles.WriteLn(inf);
  456.   END;
  457. END writeInfoStr;
  458.  
  459. PROCEDURE buildRectStr(value: Rectangle; VAR str: ARRAY OF CHAR);
  460. BEGIN
  461.   Strings.Assign ('{', str, v.bool);
  462.   RC2NDC (value);
  463.   WITH value DO
  464.     Strings.Append (StrConv.IntToStr (x, 0), str, v.bool);
  465.     Strings.Append (', ', str, v.bool);
  466.     Strings.Append (StrConv.IntToStr (y, 0), str, v.bool);
  467.     Strings.Append (', ', str, v.bool);
  468.     Strings.Append (StrConv.IntToStr (w, 0), str, v.bool);
  469.     Strings.Append (', ', str, v.bool);
  470.     Strings.Append (StrConv.IntToStr (h, 0), str, v.bool);
  471.     Strings.Append ('}', str, v.bool);
  472.   END;
  473. END buildRectStr;
  474.  
  475. PROCEDURE writeInfoRect (inf : mtTextfiles.TEXTFILE; REF name : ARRAY OF CHAR; value : Rectangle);
  476.   VAR str : MaxStr;
  477. BEGIN
  478.   writeName (inf, name);
  479.   buildRectStr (value, str);
  480.   mtTextfiles.WriteLine (inf, str);
  481.   mtTextfiles.WriteLine (inf, ';');
  482.   mtTextfiles.WriteLn(inf);
  483. END writeInfoRect;
  484. (*$W=*)
  485.  
  486. PROCEDURE reqConfBool (REF name: ARRAY OF CHAR; VAR theVar: varPtr; withDef: BOOLEAN; def: BOOLEAN): BOOLEAN;
  487.   VAR found: BOOLEAN;
  488.       str  : MaxStr;
  489. BEGIN
  490.   found := findConfVar (name, theVar);
  491.   IF reqF
  492.   THEN
  493.     writeName (reqFile, name);
  494.     IF found
  495.     THEN
  496.       buildBool (theVar^.val.boolV, str);
  497.       mtTextfiles.WriteLine (reqFile, str);
  498.     END;
  499.     mtTextfiles.WriteLine (reqFile, ';');
  500.     mtTextfiles.WriteLine (reqFile, '  [');
  501.     IF withDef
  502.     THEN
  503.       buildBool (def, str);
  504.       mtTextfiles.WriteLine (reqFile, str);
  505.     END;
  506.     mtTextfiles.WriteLine (reqFile, ']');
  507.     mtTextfiles.WriteLn(reqFile);
  508.   END;
  509.   RETURN found;
  510. END reqConfBool;
  511.  
  512. PROCEDURE reqConfStr (REF name: ARRAY OF CHAR; VAR theVar: varPtr; withDef: BOOLEAN; REF def: ARRAY OF CHAR): BOOLEAN;
  513.   VAR found: BOOLEAN;
  514.       str  : MaxStr;
  515. BEGIN
  516.   found := findConfVar (name, theVar);
  517.   IF reqF
  518.   THEN
  519.     writeName (reqFile, name);
  520.     IF found & (theVar^.type = string)
  521.     THEN
  522.       buildStr (theVar^.val.strV^, str);
  523.       mtTextfiles.WriteLine (reqFile, '"');
  524.       mtTextfiles.WriteLine (reqFile, str);
  525.       mtTextfiles.WriteLine (reqFile, '"');
  526.     END;
  527.     mtTextfiles.WriteLine (reqFile, ';');
  528.     mtTextfiles.WriteLine (reqFile, '  [');
  529.     IF withDef
  530.     THEN
  531.       buildStr (def, str);
  532.       mtTextfiles.WriteLine (reqFile, '"');
  533.       mtTextfiles.WriteLine (reqFile, str);
  534.       mtTextfiles.WriteLine (reqFile, '"');
  535.     END;
  536.     mtTextfiles.WriteLine (reqFile, ']');
  537.     mtTextfiles.WriteLn(reqFile);
  538.   END;
  539.   RETURN found;
  540. END reqConfStr;
  541.  
  542. PROCEDURE reqConfInt (REF name: ARRAY OF CHAR; VAR theVar: varPtr; withDef: BOOLEAN; def: LONGINT): BOOLEAN;
  543.   VAR found: BOOLEAN;
  544.       str  : MaxStr;
  545. BEGIN
  546.   found := findConfVar (name, theVar);
  547.   IF reqF
  548.   THEN
  549.     writeName (reqFile, name);
  550.     IF found
  551.     THEN
  552.       IF theVar^.type = lint
  553.       THEN
  554.         mtTextfiles.WriteLongInt (reqFile, theVar^.val.lintV, 0);
  555.       ELSE
  556.         mtTextfiles.WriteLongInt (reqFile, theVar^.val.intV, 0);
  557.       END;
  558.     END;
  559.     mtTextfiles.WriteLine (reqFile, ';');
  560.     mtTextfiles.WriteLine (reqFile, '  [');
  561.     IF withDef
  562.     THEN
  563.       mtTextfiles.WriteLongInt (reqFile, def, 0);
  564.     END;
  565.     mtTextfiles.WriteLine (reqFile, ']');
  566.     mtTextfiles.WriteLn(reqFile);
  567.   END;
  568.   RETURN found;
  569. END reqConfInt;
  570.  
  571. PROCEDURE reqConfRect (REF name: ARRAY OF CHAR; VAR theVar: varPtr; withDef: BOOLEAN; def: Rectangle): BOOLEAN;
  572.   VAR found: BOOLEAN;
  573.       str  : MaxStr;
  574. BEGIN
  575.   found := findConfVar (name, theVar);
  576.   IF reqF
  577.   THEN
  578.     writeName (reqFile, name);
  579.     IF found
  580.     THEN
  581.       buildRectStr (theVar^.val.rectV, str);
  582.       mtTextfiles.WriteLine (reqFile, str);
  583.     END;
  584.     mtTextfiles.WriteLine (reqFile, ';');
  585.     mtTextfiles.WriteLine (reqFile, '  [');
  586.     IF withDef
  587.     THEN
  588.       buildRectStr (def, str);
  589.       mtTextfiles.WriteLine (reqFile, str);
  590.     END;
  591.     mtTextfiles.WriteLine (reqFile, ']');
  592.     mtTextfiles.WriteLn(reqFile);
  593.   END;
  594.   RETURN found;
  595. END reqConfRect;
  596.  
  597.  
  598. (*
  599. (*$Z-*)
  600. VAR count : INTEGER;
  601.     bytes : LONGINT;
  602.     oBytes: LONGINT;
  603. PROCEDURE countEntry (entry : ADDRESS; info: ADDRESS) : BOOLEAN;
  604.   VAR theVar : varPtr;
  605. BEGIN
  606.   INC (count);
  607.   theVar := varPtr (entry);
  608.   INC (bytes, MemSize (entry)+10);
  609.   INC (bytes, TSIZE(Lists.LCarrier)+10);
  610.   INC (oBytes, 20);     (* 10 Bytes pro Malloc *)
  611.   IF theVar^.type = string
  612.   THEN
  613.     INC (bytes, MemSize (theVar^.val.strV)+10);
  614.     INC (oBytes, 10);
  615.   END;
  616.   RETURN FALSE;
  617. END countEntry;
  618. (*$Z=*)
  619. *)
  620.  
  621. (*$Z-*)
  622. PROCEDURE writeEntry (entry : ADDRESS; info : ADDRESS) : BOOLEAN;
  623.   VAR theVar : varPtr;
  624.       inf    : POINTER TO mtTextfiles.TEXTFILE;
  625. BEGIN
  626.   theVar := varPtr (entry);
  627.   inf    := info;
  628.   CASE theVar^.type OF
  629.     string : writeInfoStr (inf^, theVar^.name, theVar^.val.strV^); |
  630.     lint   : writeInfoInt (inf^, theVar^.name, theVar^.val.lintV); |
  631.     int    : writeInfoInt (inf^, theVar^.name, theVar^.val.intV); |
  632.     rect   : writeInfoRect (inf^, theVar^.name, theVar^.val.rectV); |
  633.     bool   : writeInfoBool (inf^, theVar^.name, theVar^.val.boolV); |
  634.   ELSE
  635.   END;
  636.   RETURN FALSE;
  637. END writeEntry;
  638. (*$Z=*)
  639.  
  640. (*-------- exportierte Funktionen ---------------*)
  641.  
  642. PROCEDURE GetConfigString (REF name : ARRAY OF CHAR; VAR val : ARRAY OF CHAR) : BOOLEAN;
  643.   VAR theVar : varPtr;
  644. BEGIN
  645.   IF ~reqConfStr (name, theVar, FALSE, ''+0c) THEN RETURN FALSE END;
  646.   IF theVar^.type # string THEN RETURN FALSE END;
  647.   Strings.Assign (theVar^.val.strV^, val, v.bool);
  648.   RETURN TRUE;
  649. END GetConfigString;
  650.  
  651. PROCEDURE GetConfigInt (REF name : ARRAY OF CHAR; VAR val : INTEGER): BOOLEAN;
  652.   VAR theVar : varPtr;
  653. BEGIN
  654.   IF ~reqConfInt (name, theVar, FALSE, 0) THEN RETURN FALSE END;
  655.   IF (theVar^.type # int) & (theVar^.type # lint) THEN RETURN FALSE END;
  656.   IF (theVar^.type = lint) & 
  657.      ((theVar^.val.lintV > 32767) OR (theVar^.val.lintV < 32768))
  658.   THEN 
  659.     RETURN FALSE
  660.   END;
  661.   IF theVar^.type = int 
  662.   THEN
  663.     val := theVar^.val.intV;
  664.   ELSE
  665.     val := SHORT(theVar^.val.lintV);
  666.   END;
  667.   RETURN TRUE;
  668. END GetConfigInt;
  669.  
  670. PROCEDURE GetConfigLongInt (REF name : ARRAY OF CHAR; VAR val : LONGINT): BOOLEAN;
  671.   VAR theVar : varPtr;
  672. BEGIN
  673.   IF ~reqConfInt (name, theVar, FALSE, 0) THEN RETURN FALSE END;
  674.   IF (theVar^.type # int) & (theVar^.type # lint) THEN RETURN FALSE END;
  675.   IF theVar^.type = int 
  676.   THEN
  677.     val := theVar^.val.intV;
  678.   ELSE
  679.     val := theVar^.val.lintV;
  680.   END;
  681.   RETURN TRUE;
  682. END GetConfigLongInt;
  683.  
  684. PROCEDURE GetConfigBool (REF name : ARRAY OF CHAR; VAR val : BOOLEAN): BOOLEAN;
  685.   VAR theVar : varPtr;
  686. BEGIN
  687.   IF ~reqConfBool (name, theVar, FALSE, FALSE) THEN RETURN FALSE END;
  688.   IF theVar^.type # bool THEN RETURN FALSE END;
  689.   val := theVar^.val.boolV;
  690.   RETURN TRUE;
  691. END GetConfigBool;
  692.  
  693. PROCEDURE GetConfigRect (REF name : ARRAY OF CHAR; VAR val : Rectangle): BOOLEAN;
  694.   VAR theVar : varPtr;
  695. BEGIN
  696.   IF ~reqConfRect (name, theVar, FALSE, Rectangle{0,0,0,0}) THEN RETURN FALSE END;
  697.   IF theVar^.type # rect THEN RETURN FALSE END;
  698.   val := theVar^.val.rectV;
  699.   RETURN TRUE;
  700. END GetConfigRect;
  701.  
  702. (*------------- Variablen lesen mit Default-Wert -------------------*)
  703.  
  704. PROCEDURE GetConfDefStr (REF name : ARRAY OF CHAR; VAR val : ARRAY OF CHAR;
  705.                            REF default : ARRAY OF CHAR);
  706. (* Liest eine String-Variable. Wenn die Variable nicht gefunden wird,
  707.  * dann wird der Default-Wert zurckgegeben.
  708.  *)
  709.   VAR theVar : varPtr;
  710. BEGIN
  711.   IF reqConfStr (name, theVar, TRUE, default) & (theVar^.type = string)
  712.   THEN 
  713.     Strings.Assign (theVar^.val.strV^, val, v.bool);
  714.   ELSE
  715.     Strings.Assign (default, val, v.bool);
  716.   END;
  717. END GetConfDefStr;
  718.  
  719. PROCEDURE GetConfDefInt (REF name : ARRAY OF CHAR; VAR val : INTEGER;
  720.                          default : INTEGER);
  721. (* Liest eine Integer-Variable. Wenn die Variable nicht gefunden wird,
  722.  * dann wird der Default-Wert zurckgegeben.
  723.  *)
  724.   VAR theVar : varPtr;
  725. BEGIN
  726.   IF ~reqConfInt (name, theVar, TRUE, default) THEN val := default; RETURN END;
  727.   IF (theVar^.type # int) & (theVar^.type # lint) THEN val := default; RETURN END;
  728.   IF (theVar^.type = lint) & 
  729.      ((theVar^.val.lintV > 32767) OR (theVar^.val.lintV < 32768))
  730.   THEN 
  731.     val := default;
  732.     RETURN
  733.   END;
  734.   IF theVar^.type = int 
  735.   THEN
  736.     val := theVar^.val.intV;
  737.   ELSE
  738.     val := SHORT(theVar^.val.lintV);
  739.   END;
  740. END GetConfDefInt;
  741.  
  742. PROCEDURE GetConfDefLongInt (REF name : ARRAY OF CHAR; VAR val : LONGINT;
  743.                              default : LONGINT);
  744. (* Liest eine Integer-Variable. Wenn die Variable nicht gefunden wird,
  745.  * dann wird der Default-Wert zurckgegeben.
  746.  *)
  747.  VAR theVar : varPtr;
  748. BEGIN
  749.   IF ~reqConfInt (name, theVar, TRUE, default) THEN val := default; RETURN END;
  750.   IF (theVar^.type # int) & (theVar^.type # lint) THEN val := default; RETURN END;
  751.   IF theVar^.type = int 
  752.   THEN
  753.     val := theVar^.val.intV;
  754.   ELSE
  755.     val := theVar^.val.lintV;
  756.   END;
  757. END GetConfDefLongInt;
  758.  
  759. PROCEDURE GetConfDefBool (REF name : ARRAY OF CHAR; VAR val : BOOLEAN;
  760.                           default : BOOLEAN);
  761. (* Liest eine Bool'sche Variable. Wenn die Variable nicht gefunden wird,
  762.  * dann wird der Default-Wert zurckgegeben.
  763.  *)
  764.   VAR theVar : varPtr;
  765. BEGIN
  766.   IF reqConfBool (name, theVar, TRUE, default) & (theVar^.type = bool) 
  767.   THEN
  768.     val := theVar^.val.boolV; 
  769.   ELSE
  770.     val := default;
  771.   END;
  772. END GetConfDefBool;
  773.  
  774. PROCEDURE GetConfDefRect (REF name : ARRAY OF CHAR; VAR val : Rectangle;
  775.                           default : Rectangle);
  776. (* Liest eine Rechteck-Variable. Wenn die Variable nicht gefunden wird,
  777.  * dann wird der Default-Wert zurckgegeben.
  778.  *)
  779.   VAR theVar : varPtr;
  780. BEGIN
  781.   IF reqConfRect (name, theVar, TRUE, default) & (theVar^.type = rect)
  782.   THEN
  783.     val := theVar^.val.rectV; 
  784.   ELSE
  785.     val := default;
  786.   END;
  787. END GetConfDefRect;
  788.  
  789. (*------------- Variablen schreiben -------------------*)
  790.  
  791. PROCEDURE SetConfigString (REF name : ARRAY OF CHAR; REF val : ARRAY OF CHAR) : BOOLEAN;
  792. (* Schreibt eine String-Variable. Bei TRUE konnte die Variable angelegt werden.
  793.  *)
  794.   VAR theVar : confVar;
  795. BEGIN
  796.   Strings.Assign (name, theVar.name, v.bool);
  797.   theVar.type := string;
  798.   ALLOCATE (theVar.val.strV, LENGTH (val)+1);
  799.   IF theVar.val.strV = NIL THEN RETURN FALSE END;
  800.   Strings.Assign (val, theVar.val.strV^, v.bool);
  801.   IF ~setVar (theVar)
  802.   THEN 
  803.     DEALLOCATE (theVar.val.strV, 0);
  804.     RETURN FALSE;
  805.   END;
  806.   RETURN TRUE;
  807. END SetConfigString;
  808.  
  809. PROCEDURE SetConfigInt (REF name : ARRAY OF CHAR; val : INTEGER): BOOLEAN;
  810. (* Schreibt eine Integer-Variable. Bei TRUE konnte die Variable angelegt werden.
  811.  *)
  812.   VAR theVar : confVar;
  813. BEGIN
  814.   Strings.Assign (name, theVar.name, v.bool);
  815.   theVar.type := int;
  816.   theVar.val.intV := val;
  817.   RETURN setVar (theVar);
  818. END SetConfigInt;
  819.  
  820. PROCEDURE SetConfigLongInt (REF name : ARRAY OF CHAR; val : LONGINT): BOOLEAN;
  821. (* Schreibt eine Integer-Variable. Bei TRUE konnte die Variable angelegt werden.
  822.  *)
  823.   VAR theVar : confVar;
  824. BEGIN
  825.   Strings.Assign (name, theVar.name, v.bool);
  826.   theVar.type := lint;
  827.   theVar.val.lintV := val;
  828.   RETURN setVar (theVar);
  829. END SetConfigLongInt;
  830.  
  831. PROCEDURE SetConfigBool (REF name : ARRAY OF CHAR; val : BOOLEAN): BOOLEAN;
  832. (* Schreibt eine Bool'sche Variable. Bei TRUE konnte die Variable angelegt werden.
  833.  *)
  834.   VAR theVar : confVar;
  835. BEGIN
  836.   Strings.Assign (name, theVar.name, v.bool);
  837.   theVar.type := bool;
  838.   theVar.val.boolV := val;
  839.   RETURN setVar (theVar);
  840. END SetConfigBool;
  841.  
  842. PROCEDURE SetConfigRect (REF name : ARRAY OF CHAR; val : Rectangle ): BOOLEAN;
  843. (* Schreibt eine Rechteck-Variable. Bei TRUE konnte die Variable angelegt werden.
  844.  *)
  845.   VAR theVar : confVar;
  846. BEGIN
  847.   Strings.Assign (name, theVar.name, v.bool);
  848.   theVar.type := rect;
  849.   theVar.val.rectV := val;
  850.   RETURN setVar (theVar);
  851. END SetConfigRect;
  852.  
  853. PROCEDURE DeleteConfigVar (REF name : ARRAY OF CHAR);
  854.   VAR theVar : varPtr;
  855. BEGIN
  856.   IF findConfVar (name, theVar)
  857.   THEN
  858.     Lists.RemoveEntry (confVars, v.bool);
  859.     IF theVar^.type = string
  860.     THEN 
  861.       DEALLOCATE (theVar^.val.strV, 0);
  862.     END;
  863.     DEALLOCATE (theVar, 0);
  864.   END;
  865. END DeleteConfigVar;
  866.  
  867. PROCEDURE DeleteAllVars ();
  868.   VAR theVar : varPtr;
  869. BEGIN
  870.   Lists.ResetList (confVars);
  871.   theVar := Lists.NextEntry (confVars);
  872.   WHILE theVar # NIL DO
  873.     Lists.RemoveEntry (confVars, v.bool);
  874.     IF theVar^.type = string
  875.     THEN 
  876.       DEALLOCATE (theVar^.val.strV, 0);
  877.     END;
  878.     DEALLOCATE (theVar, 0);
  879.     theVar := Lists.NextEntry (confVars);
  880.   END;
  881. END DeleteAllVars;
  882.  
  883. PROCEDURE CloseConfig ();
  884. (* Wird aufgerufen, wenn das Programm beendet wird.
  885.  * Dadurch wird ein eventuell vorhandenes Request-File
  886.  * geschlossen
  887.  *)
  888. BEGIN
  889.   IF reqF
  890.   THEN
  891.     mtTextfiles.CloseTextfile (reqFile);
  892.   END;
  893. END CloseConfig;
  894.  
  895. (*------------- File I/O ------------------------- *)
  896.  
  897.  
  898. PROCEDURE ReadConfigFile (REF filename : ARRAY OF CHAR) : BOOLEAN;
  899.   VAR inf : mtTextfiles.TEXTFILE;
  900.       cont: BOOLEAN;
  901.       line: INTEGER;
  902.       s   : MaxStr;
  903.       fname : ARRAY [0..15] OF CHAR;
  904.       s2  : MaxStr;
  905.       req : BOOLEAN;
  906.       reqName: MaxStr;
  907.       
  908. BEGIN
  909.   IF ~mtTextfiles.OpenTextfile (filename, mtTextfiles.READ, 32768, inf)
  910.   THEN 
  911.     RETURN FALSE
  912.   END;
  913.   FileNames.SplitPath (filename, s2, fname);
  914.   cont := TRUE;
  915.   line := 0;
  916.   REPEAT
  917.     mtTextfiles.ReadLine (inf, s);
  918.     mtTextfiles.ReadLn(inf);
  919.     INC(line);
  920.     cont := processLine (fname, s, line);
  921.   UNTIL mtTextfiles.EndofText (inf) OR ~cont;
  922.   IF ~cont THEN 
  923.     v.int := mtAlerts.Alert (1,"[3][CAT:|Nicht genug Speicher|fr alle Config-Variablen!][ [OK ]");
  924.   END;
  925.   mtTextfiles.CloseTextfile (inf);
  926.   GetConfDefBool (configRequest, req, FALSE);
  927.   IF req
  928.   THEN
  929.     (* Filenamen zusammenbauen *)
  930.     FileNames.ConcatName (filename, 'req', reqName);
  931.     reqF := mtTextfiles.OpenTextfile (reqName, mtTextfiles.WRITE, 32768, reqFile);
  932.   END;
  933.   RETURN cont;
  934. END ReadConfigFile;
  935.  
  936. PROCEDURE emptyInf( REF info: mtTextfiles.TEXTFILE);
  937. (* Leere Infoproc, gibt nichts aus *)
  938. END emptyInf;
  939.  
  940. PROCEDURE WriteConfigFile (REF filename : ARRAY OF CHAR; info: infoProc) : BOOLEAN;
  941.   VAR inf : mtTextfiles.TEXTFILE;
  942. BEGIN
  943.   IF ~mtTextfiles.OpenTextfile (filename, mtTextfiles.WRITE, 32768, inf)
  944.   THEN
  945.     RETURN FALSE;
  946.   END;
  947.   info (inf);
  948.   mtTextfiles.WriteLine (inf, "# "+whatString);
  949.   mtTextfiles.WriteLn (inf);
  950.   Lists.ResetList (confVars);
  951.   Lists.ScanEntries (confVars, Lists.forward, writeEntry, ADR (inf), v.bool);
  952.   mtTextfiles.CloseTextfile (inf);
  953.   RETURN TRUE;
  954. END WriteConfigFile;
  955.  
  956. PROCEDURE ConfigConfigModule (useTmpVars : BOOLEAN);
  957. BEGIN
  958.   IF useTmpVars
  959.   THEN
  960.     confVars := tmpVars;
  961.   ELSE
  962.     confVars := normalVars;
  963.   END;
  964. END ConfigConfigModule;
  965.  
  966. PROCEDURE SetConfigVarList (l : Lists.List);
  967. (* Konfiguriert das Modul um, welche Variablenliste benutzt
  968.  * wird. 
  969.  *)
  970. BEGIN
  971.   confVars := l;
  972. END SetConfigVarList;
  973.  
  974. PROCEDURE ResetConfigVarList ();
  975. (* Setzt die interne Variablenliste wieder auf die 
  976.  * normalen Configvariablen zurck. 
  977.  *)
  978. BEGIN
  979.   confVars := normalVars;
  980. END ResetConfigVarList;
  981.  
  982. BEGIN
  983.   Lists.CreateList (normalVars, v.bool);
  984.   IF v.bool THEN HALT END;
  985.   confVars := normalVars;
  986.   Lists.CreateList (tmpVars, v.bool);
  987.   IF v.bool THEN HALT END;
  988.   MagicAES.WindGet (0, MagicAES.WFWORKXYWH, deskSize);
  989.   reqF := FALSE;
  990. END ConfVars.
  991.